package com.zyd.shiro.business.service;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.zyd.shiro.business.vo.GoodsConditionVO;
import com.zyd.shiro.business.vo.GoodsEditVO;
import com.zyd.shiro.business.vo.GoodsVO;
import com.zyd.shiro.persistence.beans.*;
import com.zyd.shiro.persistence.dao.*;
import com.zyd.shiro.util.QiniuUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * 服务层
 *
 * @author RookieWZW
 */
@Service
public class MallGoodsService {

    @Autowired
    QiniuUtil qiniuUtil;
    @Autowired
    private MallGoodsDao goodsDao;

    @Autowired
    private MallCategoryDao categoryDao;

    @Autowired
    private MallGoodsImageDao goodsImageDao;

    @Autowired
    private MallGoodsSpecDao goodsSpecDao;

    @Autowired
    private MallGoodsSpecRelDao goodsSpecRelDao;

    @Autowired
    private MallGoodsRoyaltyDao royaltyDao;

    /**
     * 查询删除的商品或未被删除的商品
     *
     * @return
     */
    public List<GoodsVO> findAllByIs_delete(Integer is_delete) {
        List<Goods> goodsList = goodsDao.getAllByIs_delete(is_delete);

        return GoodsToGoodsVO(goodsList);
    }

    /**
     * 分页查询
     *
     * @param page
     * @param size
     * @return
     */
    public Page<Goods> findPage(int page, int size) {
        PageRequest pageRequest = new PageRequest(page - 1, size);
        return goodsDao.findAll(pageRequest);
    }

    private Specification<Goods> where(Map searchMap) {

        return new Specification<Goods>() {

            @Override
            public Predicate toPredicate(Root<Goods> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<Predicate>();
                // 商品名称
                if (searchMap.get("goods_name") != null && !"".equals(searchMap.get("goods_name"))) {
                    predicateList.add(cb.like(root.get("goods_name").as(String.class), "%" + (String) searchMap.get("goods_name") + "%"));
                }
                if (searchMap.get("goods_status") != null && !"".equals(searchMap.get("goods_status"))) {
                    predicateList.add(cb.equal(root.get("goods_status").as(Integer.class), searchMap.get("goods_status")));

                }
                if (searchMap.get("goods_category") != null && !"".equals(searchMap.get("goods_category"))) {

                    predicateList.add(cb.equal(root.get("category_id").as(Integer.class), searchMap.get("goods_category")));
                }

                return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));

            }
        };

    }

    public List<GoodsVO> findSearch(Map whereMap) {

        Specification<Goods> specification = where(whereMap);

        List<Goods> goodsList = goodsDao.findAll(specification);

        return GoodsToGoodsVO(goodsList);


    }

    public List<GoodsVO> voList(GoodsConditionVO vo) {

        Specification<Goods> specification = new Specification<Goods>() {
            @Override
            public Predicate toPredicate(Root<Goods> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<Predicate>();
                // 商品名称
                if (!StringUtils.isEmpty(vo.getGoods_name()))
                    predicateList.add(cb.like(root.get("goods_name").as(String.class), "%" + vo.getGoods_name() + "%"));
                if (vo.getGoods_category() != null && vo.getGoods_category() != 0)
                    predicateList.add(cb.equal(root.get("category_id").as(Integer.class), vo.getGoods_category()));
                if (vo.getGoods_status() != null && vo.getGoods_status() != 0)
                    predicateList.add(cb.equal(root.get("goods_status").as(Integer.class), vo.getGoods_status()));
                return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };

        PageRequest pageRequest = new PageRequest(vo.getPageNumber() - 1, vo.getPageSize());
        Page<Goods> goodsList = goodsDao.findAll(specification, pageRequest);

        return GoodsToGoodsVO(goodsList.getContent());


    }

    public GoodsEditVO findOne(Integer id) {
        Goods goods = goodsDao.findOne(id);

        GoodsEditVO goodsEditVO = new GoodsEditVO();
        goodsEditVO.setGoods(goods);

        List<GoodsImage> goodsImageList = goodsImageDao.findByGoods_id(goods.getId());

        goodsEditVO.setGoodsImageList(goodsImageList);

        GoodsSpec goodsSpec = goodsSpecDao.findByGoods_id(goods.getId());
        goodsEditVO.setGoodsSpec(goodsSpec);

        GoodsRoyalty royalty = royaltyDao.findByGoods_id(goods.getId());
        goodsEditVO.setRoyalty(royalty);
        return goodsEditVO;

    }

    public void add(GoodsEditVO goodsEditVO) {

        goodsEditVO.getGoods().setSales_actual(0.0);
        goodsEditVO.getGoods().setSales_initial(0.0);
        Goods goods = goodsDao.save(goodsEditVO.getGoods());
        for (GoodsImage image : goodsEditVO.getGoodsImageList()) {
            image.setGoods_id(goods.getId());
            //TODO 这里有逻辑错误，和修改之间有很大问题
        }
        goodsImageDao.save(goodsEditVO.getGoodsImageList());
        goodsEditVO.getGoodsSpec().setGoods_id(goods.getId());
        if (goodsEditVO.getRoyalty() != null) {
            goodsEditVO.getRoyalty().setGoods_id(goods.getId());
            goodsEditVO.getRoyalty().setId(0);
        }
        royaltyDao.save(goodsEditVO.getRoyalty());
        goodsSpecDao.save(goodsEditVO.getGoodsSpec());
    }

    public void update(GoodsEditVO goodsEditVO) {

        goodsDao.save(goodsEditVO.getGoods());
        Integer id = goodsEditVO.getGoods().getId();
        for (GoodsImage image : goodsEditVO.getGoodsImageList()) {
            image.setGoods_id(id);
        }
        goodsImageDao.save(goodsEditVO.getGoodsImageList());
        goodsEditVO.getGoodsSpec().setGoods_id(id);
        goodsSpecDao.save(goodsEditVO.getGoodsSpec());

    }

    public void delete(Integer id) {
        Goods goods = goodsDao.getOne(id);
        goods.setIs_delete(1);

        goodsDao.save(goods);
    }

    public void updateStatus(Integer id, int status) {
        Goods goods = goodsDao.getOne(id);
        goods.setGoods_status(status);

        goodsDao.save(goods);

    }

    public Goods unDelete(Integer id) {
        Goods goods = goodsDao.getOne(id);
        goods.setIs_delete(0);

        return goodsDao.save(goods);
    }

    public List<Goods> findPortal(Map searchMap) {


        if (searchMap.get("sortType").equals("sales")) {
            return goodsDao.getAllByCategory_idAndGoods_nameLikeOrderBySales_actualDesc(Integer.valueOf((String) searchMap.get("category_id")), (String) searchMap.get("search"));
        } else if (searchMap.get("sortType").equals("price")) {
            return goodsDao.getAllByCategory_idAndGoods_nameLikeOrderBy(Integer.valueOf((String) searchMap.get("category_id")), (String) searchMap.get("search"));
        } else {
            System.out.println(Integer.valueOf((String) searchMap.get("category_id")));
            for (int i = 0; i < 100; i++) {
                System.out.println("^^^^^^^^^^^^^^");
            }

            return goodsDao.getAllByCategory_idAndGoods_nameLike(Integer.valueOf((String) searchMap.get("category_id")), (String) searchMap.get("search"));
        }
    }


    private List<GoodsVO> GoodsToGoodsVO(List<Goods> goodsList) {
        List<GoodsVO> goodsVOList = new ArrayList<>();

        for (Goods good : goodsList) {
            GoodsVO goodsVO = new GoodsVO();
            goodsVO.setId(good.getId());
            goodsVO.setCreate_time(good.getCreate_time());
            goodsVO.setGoods_name(good.getGoods_name());
            goodsVO.setGoods_sort(good.getGoods_sort());
            goodsVO.setGoods_status(good.getGoods_status());

            Category category = categoryDao.findOne(good.getCategory_id());
            System.out.println(category.getName());
            goodsVO.setCategory_name(category.getName());
            GoodsSpec spec = goodsSpecDao.findByGoods_id(good.getId());
            goodsVO.setGoods_sales(spec.getGoods_sales());

            List<GoodsImage> goodsImageList = goodsImageDao.findByGoods_id(good.getId());
            if (goodsImageList.size() > 0) {
                try {
                    goodsVO.setImage(qiniuUtil.getFile(goodsImageList.get(0).getImage()));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }


            goodsVOList.add(goodsVO);

        }
        return goodsVOList;
    }

    //----------------------------------------------------------------------------------------------------------------------


    public List<Goods> getNewList() {

        return goodsDao.getAllByIs_deleteOrderByIdDESC(0);
    }

    public List<Goods> getBestList() {

        return goodsDao.getAllByIs_deleteOrderBySales_initialDesc(0);
    }

    public Goods detail(Integer id) {
        return goodsDao.findOne(id);
    }
}
